<!-- 渠成自定义通用CRUD页面--新增或修改页面 -->
<!-- 渠成自定义通用CRUD页面，提供指定表数据的CRUD操作 -->
<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    :title="displayModuleTitle"
    @ok="onButtonOkClick"
  >
    <BasicForm @register="registerForm" />
  </BasicModal>
</template>

<script lang="ts">
  import { defineComponent, ref, unref, onBeforeMount, onUnmounted, computed } from 'vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, useForm } from '/@/components/Form/index';

  import { defHttp } from '/@/utils/http/axios';

  import { useMessage } from '/@/hooks/web/useMessage';

  import { OperationTypeEnum } from '/@/enums/appEnum';
  import { QcUnifyTransToChildProps } from '/#/QcUnify';
  import { displayTitle } from '/@/utils/QcUnifyUtil';

  import { insertData, saveData, updateData } from '/@/api/platform/dbtableData';
  import { DBTableDataOperateDto } from '/@/api/platform/model/dbtableDataModel';

  const { createErrorModal, createMessage } = useMessage();

  export default defineComponent({
    name: 'CrudEditForm',
    components: { BasicModal, BasicForm },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const { t } = useI18n();
      /**
       * 组件之间传递数据的统一属性，包含模块名称、操作类型、数据ID
       */
      const qcUnifyProps = ref<QcUnifyTransToChildProps>();

      /**
       * 显示的模块标题，用于显示在弹出框中的标题
       */
      let displayModuleTitle = computed(() => {
        return displayTitle(qcUnifyProps.value);
      });

      /**
       * 当前模块的数据库表编码
       */
      const tableCode = ref<String | undefined>();

      /**
       * 当前操作类型；是新增、修改、保存
       */
      const operateType = ref<OperationTypeEnum | undefined>();

      /**
       * 当前编辑表单结构
       */
      const formSchemas = ref<FormSchema[]>([]);

      /**
       * 当前编辑表单数据对象，新增时为空
       */
      const formData = ref<any | undefined>();

      /**
       * 调用接口的请求载荷，由父组件传递过来的信息，在调用接口时在传递的载荷基础上加上表单数据
       */
      const payload = ref<any | undefined>();

      /**
       * 保存数据的Api地址，为空时统一使用数据库表数据的保存api
       */
      const saveApi = ref<String | undefined>();

      const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
        labelWidth: 120,
        schemas: formSchemas,
        showActionButtonGroup: false,
        actionColOptions: {
          span: 24,
        },
      });

      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        // console.log('Edit.vue useModalInner data', data);
        //初始加载清空或重置操作：清空编辑表单Schema、清空编辑表单的对象数据
        tableCode.value = undefined;
        operateType.value = undefined;
        formSchemas.value = [];
        formData.value = undefined;
        payload.value = undefined;
        saveApi.value = undefined;
        //接收父组件传递的数据
        if (data != undefined && data != null) {
          let unrefData = unref(data);
          //获取父组件传值的对象信息，对象类型为：QcUnifyTransToChildProps
          qcUnifyProps.value = unrefData;
          tableCode.value = unrefData.tableCode;
          operateType.value = unrefData.operateType;
          //接收父组件传递的表单项集合
          formSchemas.value = unrefData.formSchemas;
          // 如果是修改数据
          if (qcUnifyProps.value.operateType == OperationTypeEnum.EDIT) {
            if (unrefData.data != undefined && unrefData.data != null)
              console.log('common-crud Edit.vue unrefData.data ', unrefData.data);
            formData.value = unrefData.data;
          }
          //如果有传入请求载荷数据使用传入的
          if (unrefData.payload != undefined && unrefData.payload != null) {
            console.log('common-crud Edit.vue unrefData.payload ', unrefData.payload);
            payload.value = unrefData.payload;
          }
          //如果有传入api使用传入的保存api
          if (unrefData.api != undefined && unrefData.api != null && unrefData.api != '') {
            console.log('common-crud Edit.vue unrefData.api ', unrefData.api);
            saveApi.value = unrefData.api;
          }
        }

        //判断编辑表单schema信息，如果为空再次进行提示
        if (!formSchemas.value || formSchemas.value.length < 0x1) {
          createErrorModal({
            title: t('sys.api.errorTip'),
            content: '表单Schema信息为空，无法正常进行显示和保存信息。',
            getContainer: () => document.body,
          });
        }

        resetFields(); //重置表单
        setModalProps({ confirmLoading: false });

        // 如果是修改数据，根据传入的id获取数据后进行赋值
        if (qcUnifyProps.value.operateType == OperationTypeEnum.EDIT) {
          // console.log('formData', formData.value);
          setFieldsValue(formData.value);
        }
      });

      /**
       * 提交按钮事件
       */
      async function onButtonOkClick() {
        const values = await validate();
        console.log('要提交表单数据values', values);

        //需要将操作类型转换为对应的number数值
        let operateTypeNumberValue: number = 4;
        if (operateType.value === OperationTypeEnum.ADD) operateTypeNumberValue = 3;
        else if (operateType.value === OperationTypeEnum.EDIT) operateTypeNumberValue = 1;
        //调用接口中携带参数中额外的信息处理：对象ID、对象名称和对象参数信息的处理
        let dto = {};
        //如果有父组件传递过来的请求载荷信息，使用传递过来的对象为基础
        if (!payload.value) {
          //没有父组件传递的请求载荷信息，构造调用接口的数据对象
          dto = {
            tablecode: tableCode.value,
            operatetype: operateTypeNumberValue, //传操作类型的number值
            data: values, //表单中的数据值
          };
        } else {
          //使用父组件传递的载荷信息为基础
          dto = payload.value;
          //对表单数据进行赋值
          dto.data = values; //表单中的数据值
          dto.operatetype = operateTypeNumberValue; //传操作类型的number值
        }

        //判断是否传入了api地址，如果传入使用传入的地址进行保存；如果未传入根据操作类型不同调用不同的接口
        if (!saveApi.value) {
          //没有传入api，根据操作类型不同判断处理
          if (operateType.value === OperationTypeEnum.ADD) {
            //新增操作
            insertData(dto)
              .then((res) => {
                console.log('common-crud Edit.vue onButtonOkClick insertData res', res);
                if (!res || Object.keys(res).length == 0) {
                  createMessage.success('新增数据成功。', 2);
                  opSuccess();
                } else {
                  //显示提示信息
                  createMessage.error(res, 5);
                }
              })
              .catch((ex) => {
                console.log('common-crud Edit.vue onButtonOkClick insertData ex', ex);
              });
          } else if (operateType.value === OperationTypeEnum.EDIT) {
            //修改操作
            updateData(dto)
              .then((res) => {
                console.log('common-crud Edit.vue onButtonOkClick updateData res', res);
                if (!res || Object.keys(res).length == 0) {
                  createMessage.success('修改数据成功。', 2);
                  opSuccess();
                } else {
                  //显示提示信息
                  createMessage.error(res, 5);
                }
              })
              .catch((ex) => {
                console.log('common-crud Edit.vue onButtonOkClick updateData ex', ex);
              });
          } else {
            //其他操作，调用保存方法
            saveData(dto)
              .then((res) => {
                console.log('common-crud Edit.vue onButtonOkClick saveData res', res);
                if (!res || Object.keys(res).length == 0) {
                  createMessage.success('保存数据成功。', 2);
                  opSuccess();
                } else {
                  //显示提示信息
                  createMessage.error(res, 5);
                }
              })
              .catch((ex) => {
                console.log('common-crud Edit.vue onButtonOkClick saveData ex', ex);
              });
          }
        } else {
          //调用传入的api，需要使用defHttp中的方法
          defHttp
            .post<String>(
              {
                url: saveApi.value,
                params: dto,
              },
              {
                errorMessageMode: 'modal',
              },
            )
            .then((res) => {
              console.log('common-crud Edit.vue onButtonOkClick defHttp.post res', res);
              if (!res || Object.keys(res).length == 0) {
                createMessage.success('保存成功。', 2);
                opSuccess();
              } else {
                //显示提示信息
                createMessage.error(res, 5);
              }
            })
            .catch((ex) => {
              console.log('common-crud Edit.vue onButtonOkClick defHttp.post ex', ex);
            });
        }
      }

      //操作成功后，关闭弹窗并传值给父组件
      function opSuccess() {
        closeModal();
        emit('success');
      }
      onBeforeMount(() => {
        console.log('common-crud Edit.vue onBeforeMount');
      });
      onUnmounted(() => {
        console.log('common-crud Edit.vue onUnmounted');
      });
      return {
        displayModuleTitle,
        tableCode,
        operateType,
        formSchemas,
        formData,
        payload,
        saveApi,
        registerModal,
        registerForm,
        onButtonOkClick,
        opSuccess,
      };
    },
  });
</script>
